// 把对象转换成 查询字符串
function querystringify(obj) {
    let str = ''
  
    for (var key in obj) {
      str += key + '=' + obj[key] + '&'
    }
  
    return str.slice(0, -1)
  }  
   
  // ajax 封装
  
  
  function ajax(options = {}) {
    // options 就是你传递进来的所有对于本次请求的配置信息
    // console.log('你传递进来的数据 : ', options)
  
    // 1. 参数验证
    // 1-1. 验证 options.url
    if (!options.url) {
      // 表示 url 是 undefined 或者 null 或者 '' 或者 0
      // 手动抛出异常
      // 语法: throw new Error('报错信息')
      // 作用: 直接在控制台报错, 阻断程序的继续执行
      throw new Error('url 为必填选项, 请填写 ^_^')
    }
  
    // 1-2. 验证 options.method
    // 可以是 undefined, 可以是 'GET', 可以是 'POST'
    if (!(options.method === undefined || /^(get|post)$/i.test(options.method))) {
      // 代码能执行到这里, 说明你的 method 不是 undefined 不是 get 不是 post
      throw new Error('目前版本只接受 GET 和 POST 请求, 请期待更新 !! (#^.^#)')
    }
  
    // 1-3. 验证 options.async
    // 可以是 undefined, 可以是 布尔值
    if (!(options.async === undefined || typeof options.async === 'boolean')) {
      throw new Error('async 只能传递 布尔值, 请检查后操作')
    }
  
    // 1-4. 验证 options.data
    if (!(options.data === undefined || typeof options.data === 'string')) {
      throw new Error('data 需要传递一个 字符串 格式')
    }
  
    // 1-5. 验证 options.token
    if (!(options.token === undefined || typeof options.token === 'string')) {
      throw new Error('token 需要传递一个 字符串 格式')
    }
  
    // 1-6. 验证 options.dataType
    if (!(options.dataType === undefined || /^(string|json)$/i.test(options.dataType))) {
      throw new Error('dataType 只能传递 "string" 或者 "json"')
    }
  
    // 1-7. 验证 options.success
    if (!(options.success === undefined || typeof options.success === 'function')) {
      throw new Error('success 需要传递一个 function 类型的数据')
    }
  
    // 2. 设置一套默认值
    const _default = {
      // 代码能执行到这里, 说明 url 必须有值
      url: options.url,
      // 代码能来到这里, 说明 method 要么是 undefined, 要么是 GET, 要么是 POST
      method: options.method || 'GET',
      // 代码能来到这里, 说明 async 要么是 undefined, 要么是 true 要么是 false
      async: typeof options.async === 'boolean' ? options.async : true,
      // async: options.async ?? true
      // 代码能来到这里, 说明 data 要么是 undefined, 要么是 字符串
      data: options.data || '',
      // 代码能来到这里, 说明 token 要么是 undefined, 要么是 字符串
      token: options.token || '',
      // 代码能来到这里, 说明 dataType 要么是 undefined, 要么是 string 或者 json
      dataType: options.dataType || 'string',
      // 代码能来到这里, 说明 success 要么是 undefined, 要么是一个 函数
      success: options.success || function () {},
      error: options.error || function () {}
    }
    // 2-2. 判断一下, 如果是 GET 请求, 并且 data 有内容
    // 那么我们直接把 data 拼接到 url 的后面
    if (_default.method.toUpperCase() === 'GET' && _default.data) {
      // 代码能来到这里, 说明 是 GET 请求, 并且 data 有内容
      _default.url += '?' + _default.data
    }
  
    // 3. 按照 _default 内的内容发送请求
  
    // 3-1. 创建 ajax 对象
    const xhr = new XMLHttpRequest()
  
    // 3-2. 配置请求信息
    xhr.open(_default.method, _default.url, _default.async)
  
    // 3-3. 接受响应
    xhr.onload = function () {
      // 判断一下, 如果 dataType 是 'string' 那么我就不执行 JSON.parse()
      // 如果你的 dataType 是 'json' 那么我就执行一下 JSON.parse()
      const result = _default.dataType.toUpperCase() === 'JSON' ? JSON.parse(xhr.responseText) : xhr.responseText
  
      // 请求完成, 只要调用 success 函数就可以了
      _default.success(result)
    }
  
    // 3-4. 是否填写 token 作为请求头内的一个信息
    if (_default.token) xhr.setRequestHeader('authorization', _default.token)
  
    // 3-5. 如果是 POST 请求, 设置一下请求头的格式
    if (_default.method.toUpperCase() === 'POST') xhr.setRequestHeader('content-type', 'application/x-www-form-urlencoded')
  
    // 3-6. 发送请求
    // 如果是 GET 请求, 直接书写 xhr.send()
    // 如果是 POST 请求你, 书写 xhr.send(参数)
    _default.method.toUpperCase() === 'POST' ? xhr.send(_default.data) : xhr.send()
  }
  
  
  // 对 ajax 进行 二次封装
  function pAjax(options = {}) {
    const p = new Promise((resolve, reject) => {
      // 执行 ajax
      ajax({
        url: options.url,
        data: options.data,
        token: options.token,
        async: options.async,
        method: options.method,
        dataType: options.dataType,
        success: function (res) {
          resolve(res)
        }
      })
    })
  
    // 把我的 promise 对象返回出去
    return p
  }
  

/**
 * 设置 cookie
 * @param {String} key 你要设置的 cookie 的 key
 * @param {String} value 你要设置的 cookie 的 value
 * @param {Number} expires 你要设置的 cookie 的过期时间(单位是秒)
 * @returns 无
 */
 function setcookie(key, value, expires) {
  if (!expires) return document.cookie = `${ key }=${ value }`
  const time = new Date()
  time.setTime(time.getTime() - 1000 * 60 * 60 * 8 + 1000 * expires)
  document.cookie = `${ key }=${ value };expires=${ time }`
}

/**
 * 获取 cookie
 * @param {String} key 选填, 你要获取的 cookie 的 key
 * @returns { Object | String }
 */
function getcookie(key) {
  const obj = {}
  document.cookie.split('; ').forEach(item => {
    const t = item.split('=')
    obj[t[0]] = t[1]
  })
  return key ? obj[key] : obj
}


/**
 * 删除 cookie
 * @param {String} key 你要删除的 cookie 的 key
 */
function delcookie(key) {
  setcookie(key, '', -1)
}



